package com.seed.core.manager.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seed.core.exception.DAOException;
import com.seed.core.manager.Manager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 持久层对象
 *
 * @author gchiaway
 * 日期: 2020-01-17
 * 时间: 14:30
 */
public abstract class AbstractManager<M extends BaseMapper<T>, T> implements Manager<T> {
    @Autowired
    protected M mapper;

    /**
     * 持久化
     *
     * @param model 需要保存的对象
     * @return 是否成功
     * @throws DAOException 持久层通用错误
     */
    @Override
    public Boolean save(T model) throws DAOException {
        try {
            return mapper.insert(model) > 0;
        } catch (Exception e) {
            throw new DAOException(e, model);
        }
    }

    /**
     * 批量持久化
     *
     * @param models 需要保存的对象们
     * @return 是否成功
     * @throws DAOException 持久层通用错误
     */
    @Override
    public Boolean save(List<T> models) throws DAOException {
        try {
            for (T model : models) {
                if (!this.save(model)) {
                    return false;
                }
            }
        } catch (Exception e) {
            throw new DAOException(e, models);
        }
        return true;
    }

    /**
     * 根据主键删除
     *
     * @param id 主键
     * @return 是否成功
     * @throws DAOException 持久层通用错误
     */
    @Override
    public Boolean deleteById(Object id) throws DAOException {
        try {
            return mapper.deleteById((Serializable) id) > 0;
        } catch (Exception e) {
            throw new DAOException(e, id);
        }
    }

    /**
     * 批量刪除
     *
     * @param ids eg：ids -> “1,2,3,4”
     * @return 是否成功
     * @throws DAOException 持久层通用错误
     */
    @Override
    public Boolean deleteByIds(String ids) throws DAOException {
        try {
            if (StringUtils.isEmpty(ids)) {
                return false;
            }
            List<String> idList = Arrays.asList(ids.split(","));
            return mapper.deleteBatchIds(idList) > 0;
        } catch (Exception e) {
            throw new DAOException(e, ids);
        }
    }

    /**
     * 更新，完全更新
     *
     * @param model 需要更新的对象
     * @return 是否成功
     * @throws DAOException 持久层通用错误
     */
    @Override
    public Boolean updateById(T model) throws DAOException {
        try {
            return mapper.updateById(model) > 0;
        } catch (Exception e) {
            throw new DAOException(e, model);
        }
    }

    /**
     * 批量更新
     *
     * @param newData   更新的数据
     * @param queryData 查询条件
     * @return 是否成功
     * @throws DAOException 持久层通用错误
     */
    @Override
    public Boolean updateBatch(T newData, T queryData) throws DAOException {
        UpdateWrapper<T> updateWrapper = new UpdateWrapper<>(queryData);
        try {
            return mapper.update(newData, updateWrapper) > 0;
        } catch (Exception e) {
            throw new DAOException(e, newData, queryData);
        }
    }

    /**
     * 通过主键查找
     *
     * @param id 主键
     * @return 查找到的单个对象
     * @throws DAOException 持久层通用错误
     */
    @Override
    public T getModel(Object id) throws DAOException {
        try {
            return mapper.selectById((Serializable) id);
        } catch (Exception e) {
            throw new DAOException(e, id);
        }
    }

    /**
     * 通过多个ID查找
     *
     * @param ids eg：ids -> “1,2,3,4”
     * @return 查到的多个对象
     * @throws DAOException 持久层通用错误
     */
    @Override
    public List<T> listModels(String ids) throws DAOException {
        try {
            if (StringUtils.isEmpty(ids)) {
                return new ArrayList<>();
            }
            List<String> idList = Arrays.asList(ids.split(","));
            return mapper.selectBatchIds(idList);
        } catch (Exception e) {
            throw new DAOException(e, ids);
        }
    }

    /**
     * 通过Model中某个成员变量名称（非数据表中column的名称）查找,value需符合unique约束
     * 字段值如果要传空，请传null或者空字符串
     *
     * @param fieldName 字段名称
     * @param value     字段值
     * @return 查找到的对象
     * @throws DAOException 持久层通用错误
     */
    @Override
    public List<T> listModels(String fieldName, Object value) throws DAOException {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isEmpty(value)) {
            queryWrapper.isNull(fieldName);
        } else {
            queryWrapper.eq(fieldName, value);
        }
        try {
            return mapper.selectList(queryWrapper);
        } catch (Exception e) {
            throw new DAOException(e, fieldName + ":" + value);
        }
    }

    /**
     * 通过Model中某个成员变量名称（非数据表中column的名称）分页查找,value需符合unique约束
     *
     * @param fieldName 字段名称
     * @param value     字段值
     * @param page      分页条件
     * @return 查找到的对象
     * @throws DAOException 持久层通用错误
     */
    @Override
    public IPage<T> listModels(String fieldName, Object value, Page<T> page) throws DAOException {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(fieldName, value);
        try {
            return mapper.selectPage(page, queryWrapper);
        } catch (Exception e) {
            throw new DAOException(e, fieldName + ":" + value, page);
        }
    }

    /**
     * 通过Model中某个成员变量名称（非数据表中column的名称）查找,value需符合unique约束
     *
     * @param model 对象
     * @return 查找到的对象列表
     * @throws DAOException 持久层通用错误
     */
    @Override
    public List<T> listModels(T model) throws DAOException {
        try {
            QueryWrapper<T> queryWrapper = new QueryWrapper<>(model);
            return mapper.selectList(queryWrapper);
        } catch (Exception e) {
            throw new DAOException(e, model);
        }
    }

    /**
     * 通过Model中某个成员变量名称（非数据表中column的名称）查找,value需符合unique约束
     *
     * @param model 对象
     * @param page  分页条件
     * @return 查找到的单个对象
     * @throws DAOException 持久层通用错误
     */
    @Override
    public IPage<T> listModels(T model, Page<T> page) throws DAOException {
        try {
            QueryWrapper<T> queryWrapper = new QueryWrapper<>(model);
            return mapper.selectPage(page, queryWrapper);
        } catch (Exception e) {
            throw new DAOException(e, model, page);
        }
    }

    /**
     * 获取所有
     *
     * @return 查到的多个对象
     * @throws DAOException 持久层通用错误
     */
    @Override
    public List<T> listAllModels() throws DAOException {
        try {
            QueryWrapper<T> queryWrapper = Wrappers.emptyWrapper();
            return mapper.selectList(queryWrapper);
        } catch (Exception e) {
            throw new DAOException(e);
        }
    }


}
